#ifndef MDTX_USE_RCPPARMADILLO
#define MDTX_USE_RCPPARMADILLO
#endif

#include <RcppArmadillo.h>
using namespace Rcpp;

#include "mdtx-online/indicator/indicator_type_s2_var.h"
using namespace mdtx::online;

#include "indi_common.h"

using variance_ = indi1<indicator::variance>;

//' Rolling variance
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector variance(NumericVector x, int period)
{
    auto c = variance_::create_t(period);
    return variance_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP variance_new(int period)
{
    return variance_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector variance_run(SEXP ptr, NumericVector x)
{
    return variance_::run(ptr, x);
}

using variance_ew_ = indi1<indicator::variance_ew>;

//' Rolling variance, exponentially weighted
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector variance_ew(NumericVector x, int period)
{
    auto c = variance_ew_::create_t(period);
    return variance_ew_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP variance_ew_new(int period)
{
    return variance_ew_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector variance_ew_run(SEXP ptr, NumericVector x)
{
    return variance_ew_::run(ptr, x);
}

using variance_cu_ = indi1<indicator::variance_cu>;

//' Cumulative variance
//'
//' @param x Numeric vector
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector variance_cu(NumericVector x)
{
    auto c = variance_cu_::create_t();
    return variance_cu_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP variance_cu_new()
{
    return variance_cu_::create();
}

// [[Rcpp::export(rng = false)]]
NumericVector variance_cu_run(SEXP ptr, NumericVector x)
{
    return variance_cu_::run(ptr, x);
}

using variance_vw_ = indi1<indicator::variance_vw>;

//' Volume weighted moving variance
//'
//' @param price Numeric vector of price
//' @param volume Numeric vector of volume
//' @param period Period of rolling window
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector variance_vw(NumericVector price, NumericVector volume, int period)
{
    auto c = variance_vw_::create_t(period);
    return variance_vw_::run_t(c, price, volume);
}

// [[Rcpp::export(rng = false)]]
SEXP variance_vw_new(int period)
{
    return variance_vw_::create(period);
}

// [[Rcpp::export(rng = false)]]
NumericVector variance_vw_run(SEXP ptr, NumericVector price, NumericVector volume)
{
    return variance_vw_::run(ptr, price, volume);
}

using variance_cuvw_ = indi1<indicator::variance_cuvw>;

//' Cumulative volume weighted moving variance
//'
//' @param price Numeric vector of price
//' @param volume Numeric vector of volume
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector variance_cuvw(NumericVector price, NumericVector volume)
{
    auto c = variance_cuvw_::create_t();
    return variance_cuvw_::run_t(c, price, volume);
}

// [[Rcpp::export(rng = false)]]
SEXP variance_cuvw_new()
{
    return variance_cuvw_::create();
}

// [[Rcpp::export(rng = false)]]
NumericVector variance_cuvw_run(SEXP ptr, NumericVector price, NumericVector volume)
{
    return variance_cuvw_::run(ptr, price, volume);
}

using volatility_ = indi1<indicator::volatility>;

//' Annualised volatility
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param annualise days of annualisation
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector volatility(NumericVector x, int period, int annualise = 250)
{
    auto c = volatility_::create_t(period, annualise);
    return volatility_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP volatility_new(int period, int annualise = 250)
{
    return volatility_::create(period, annualise);
}

// [[Rcpp::export(rng = false)]]
NumericVector volatility_run(SEXP ptr, NumericVector x)
{
    return volatility_::run(ptr, x);
}

using volatility_ew_ = indi1<indicator::volatility_ew>;

//' Annualised volatility, exponentially weighted
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param annualise days of annualisation
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector volatility_ew(NumericVector x, int period, int annualise = 250)
{
    auto c = volatility_ew_::create_t(period, annualise);
    return volatility_ew_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP volatility_ew_new(int period, int annualise = 250)
{
    return volatility_ew_::create(period, annualise);
}

// [[Rcpp::export(rng = false)]]
NumericVector volatility_ew_run(SEXP ptr, NumericVector x)
{
    return volatility_ew_::run(ptr, x);
}

using volatility_cu_ = indi1<indicator::volatility_cu>;

//' Cumulative annualised volatility
//'
//' @param x Numeric vector
//' @param annualise days of annualisation
//' @return Numeric vector
//' @export
// [[Rcpp::export(rng = false)]]
NumericVector volatility_cu(NumericVector x, int annualise = 250)
{
    auto c = volatility_cu_::create_t(annualise);
    return volatility_cu_::run_t(c, x);
}

// [[Rcpp::export(rng = false)]]
SEXP volatility_cu_new(int annualise = 250)
{
    return volatility_cu_::create(annualise);
}

// [[Rcpp::export(rng = false)]]
NumericVector volatility_cu_run(SEXP ptr, NumericVector x)
{
    return volatility_cu_::run(ptr, x);
}
